/*
 * PunterosHandler.cpp
 *
 *  Created on: 25/11/2011
 *      Author: putaro
 */
#include "PunterosHandler.h"
#include "Codificacion.h"
#include "GeneradorPunteros.h"
#include <cmath>
/*
 * Pre: El parámetro es la ruta del directorio donde se encuentra el archivo
 * con los datos acerca de los punteros.
 * Post: Se ha creada la instancia abriendo el archivo correspondiente.
 */
PunterosHandler::PunterosHandler(const string & ruta) {
	string rutaCompleta(ruta);
	rutaCompleta.append("/");
	rutaCompleta.append(NOMBRE_ARCHIVO_PUNTEROS);
	this -> archivo.open(rutaCompleta.c_str(), ios::in | ios::binary);
	this -> bufferLectura = 0;
	this -> datosRestantes = 0;
	this -> posicionBufferLectura = 0;
	if(archivo.is_open())
		this->seek(0);
}

/*
 * Pre: La instancia ha sido creada.
 * Post: Se ha destruido la instancia cerrando archivos y liberando el resto de los
 * recursos asociados.
*/
PunterosHandler::~PunterosHandler() {
	this ->archivo.close();
}

/*
 * Pre: La instancia ha sido creada y el parámetro es el offset al puntero.
 * Post: Se ha posicionado la lectura en el bit correspondiente al offset dado
 * por parámetro.
 * Returns: Verdadero si se pudo posicionar la lectura en la posición dada por
 * el offset.
*/
void PunterosHandler::seek(const unsigned int offset){
	//compruebo si es múltiplo de 42
	unsigned int numeroByte = floor(offset / 8);
	unsigned int resto = offset % 8;
	//posiciono al byte
	this -> archivo.seekg(numeroByte , ios::beg);
	this -> archivo.read(reinterpret_cast<char *>(&bufferLectura),sizeof(int));
	if(resto != 0){
		this -> posicionBufferLectura = 8*sizeof(int) - (offset-8*numeroByte);
	} else {
		this -> posicionBufferLectura = 8*sizeof(int);
	}
}

/*
 * Pre: La instancia ha sido creada.
 * Post: Se ha obtenido el bit siguiente a la posición actual.
*/
unsigned int PunterosHandler::getBit(){
	int retorno = 0;
	retorno = 1 & (this->bufferLectura>>(this->posicionBufferLectura-1));
	this->posicionBufferLectura--;
	if(posicionBufferLectura == 0) {
		this -> archivo.read(reinterpret_cast<char *>(&bufferLectura),sizeof(int));
		this -> posicionBufferLectura = 8*sizeof(int);
	}
	return retorno;
}

/*
 * Pre: La instancia ha sido creada.
 * Post: Se han seteado los parámetros puntero y frecuencia, con los datos recuperados
 * del archivo codificado.
*/
void PunterosHandler::getPunteroFrecuencia(unsigned int & puntero, unsigned int & frecuencia){
	puntero = Codificacion::decodificarDelta(*this);
	frecuencia = Codificacion::decodificarDelta(*this);
}
